Sesión 3

Curso: R para usuarios de Stata


Percy Soto-Becerra, M.D., M.Sc(c)

InkaStats Academy | Medical Branch

2023

https://github.com/psotob91

Análisis Inicial de datos

Análisis Inicial de datos

Inspeccionar/Explorar datos

  • Heche un vistazo de los datos con glimpse():
glimpse(datos)
Rows: 285
Columns: 9
$ id              <dbl> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,…
$ edad            <dbl> 23, 24, 24, 23, 24, 26, 25, 27, 25, 26, 28, 28, 27, 29…
$ sexo            <chr> "Femenino", "Masculino", NA, "Femenino", "Femenino", "…
$ comorb          <chr> "No", "No", "No", "No", "No", "No", "No", "No", "No", …
$ tipo_refuerzo   <chr> "Heterologo", "Heterologo", "Heterologo", "Heterologo"…
$ tdosis_refuerzo <dbl> 233, 232, 242, 234, 236, 241, 201, 241, 212, 239, 246,…
$ ant_COV         <chr> "Prior Infection", "Prior Infection", "No Infection", …
$ IgG_Basal       <dbl> 99.79, 41.34, 413.50, 13.42, 4.83, 21.70, 8.70, 10.81,…
$ IgG_Final       <dbl> 554.63, 549.02, 485.43, 573.46, 473.81, 603.79, 532.84…
  • La función skim() del paquete [skim]r]{.plo} genera un resumen global de los datos:
skim(datos)
Data summary
Name datos
Number of rows 285
Number of columns 9
_______________________
Column type frequency:
character 4
numeric 5
________________________
Group variables None

Variable type: character

skim_variable n_missing complete_rate min max empty n_unique whitespace
sexo 1 1 8 9 0 2 0
comorb 0 1 2 2 0 2 0
tipo_refuerzo 0 1 0 10 1 3 0
ant_COV 0 1 12 15 0 2 0

Variable type: numeric

skim_variable n_missing complete_rate mean sd p0 p25 p50 p75 p100 hist
id 0 1 143.00 82.42 1.00 72.00 143.00 214.00 285.00 ▇▇▇▇▇
edad 0 1 48.25 14.71 23.00 36.00 46.00 59.00 97.00 ▇▇▇▂▁
tdosis_refuerzo 0 1 214.47 25.28 134.00 199.00 222.00 235.00 267.00 ▁▂▃▇▁
IgG_Basal 1 1 82.54 122.33 -2.19 8.15 28.33 96.33 583.97 ▇▁▁▁▁
IgG_Final 0 1 492.26 71.15 235.51 447.18 501.20 545.15 618.44 ▁▁▃▇▅
  • La función describe() del paquete Hmisc genera un reporte general bien detallado, variable por variable:
describe(datos)
datos 

 9  Variables      285  Observations
--------------------------------------------------------------------------------
id : ID de paciente  Format:%9.0g 
       n  missing distinct     Info     Mean      Gmd      .05      .10 
     285        0      285        1      143    95.33     15.2     29.4 
     .25      .50      .75      .90      .95 
    72.0    143.0    214.0    256.6    270.8 

lowest :   1   2   3   4   5, highest: 281 282 283 284 285
--------------------------------------------------------------------------------
edad  Format:%10.0g 
       n  missing distinct     Info     Mean      Gmd      .05      .10 
     285        0       60    0.999    48.25    16.72       28       31 
     .25      .50      .75      .90      .95 
      36       46       59       68       72 

lowest : 23 24 25 26 27, highest: 78 79 92 94 97
--------------------------------------------------------------------------------
sexo : genero 
       n  missing distinct 
     284        1        2 
                              
Value       Femenino Masculino
Frequency        189        95
Proportion     0.665     0.335
--------------------------------------------------------------------------------
comorb : comorbilidad 
       n  missing distinct 
     285        0        2 
                      
Value         No    Sí
Frequency    214    71
Proportion 0.751 0.249
--------------------------------------------------------------------------------
tipo_refuerzo  Format:%10s 
       n  missing distinct 
     284        1        2 
                                
Value      Heterologo   Homologo
Frequency         228         56
Proportion      0.803      0.197
--------------------------------------------------------------------------------
tdosis_refuerzo : FV3_FV2  Format:%10.0g 
       n  missing distinct     Info     Mean      Gmd      .05      .10 
     285        0       89    0.999    214.5    27.56    161.2    176.0 
     .25      .50      .75      .90      .95 
   199.0    222.0    235.0    237.0    241.0 

lowest : 134 151 152 153 154, highest: 247 248 251 252 267
--------------------------------------------------------------------------------
ant_COV 
       n  missing distinct 
     285        0        2 
                                          
Value         No Infection Prior Infection
Frequency              201              84
Proportion           0.705           0.295
--------------------------------------------------------------------------------
IgG_Basal : igG pre refuerzo  Format:%10.0g 
       n  missing distinct     Info     Mean      Gmd      .05      .10 
     284        1      280        1    82.54    110.1    2.002    3.499 
     .25      .50      .75      .90      .95 
   8.155   28.325   96.325  266.028  412.019 

lowest :  -2.19   0.12   0.31   0.32   0.46, highest: 490.21 517.96 528.28 529.36 583.97
--------------------------------------------------------------------------------
IgG_Final : igG post refuerzo  Format:%10.0g 
       n  missing distinct     Info     Mean      Gmd      .05      .10 
     285        0      283        1    492.3    79.27    360.0    402.4 
     .25      .50      .75      .90      .95 
   447.2    501.2    545.1    572.7    594.1 

lowest : 235.51 246.25 290.47 300.55 309.48, highest: 608.42 611.89 614.52 615.54 618.44
--------------------------------------------------------------------------------

Nuestro turno



  • Cree una carpeta denomianda taller3.

  • Defina un proyecto RStudio en esta carpeta.

  • Configure el archivo quarto.

  • Con los datos de gapminder.dta, realice algunas exploraciones iniciales.



 

10:00

Análisis Inicial de Datos

Paso 2: Detecte y maneje duplicados

  • La función get_dupes() del paquete {janitor} es útil para esto.

  • Si solo colocamos get_dupes(), entonces nos identifica duplicados de fila completa:

library(janitor)
datos %>% 
  get_dupes()
 [1] id_jaula     id_raton     tratamiento  protocolo    peso_inicial
 [6] peso_final   peso_utero   chol         glucose      tag         
[11] prot         urea         album        dupe_count  
<0 rows> (or 0-length row.names)
  • Si colocamos una o más variables dentro de get_dupes(), entonces nos identifica duplicados solo de esa variable.

  • A menudo lo hacemos para encontrar individus duplicados.

datos %>% 
  get_dupes(id_raton)
 [1] id_raton     dupe_count   id_jaula     tratamiento  protocolo   
 [6] peso_inicial peso_final   peso_utero   chol         glucose     
[11] tag          prot         urea         album       
<0 rows> (or 0-length row.names)
  • Si el duplicado es erróneo, lo podemos eliminar con distinct() y el argumento .keep_all = TRUE.

  • Se debde espeficiar si el duplicado es de fila o de alguna variable (p. ej., id).

datos <- datos %>% 
  distinct(id_raton, .keep_all = TRUE)

datos
   id_jaula id_raton               tratamiento protocolo peso_inicial
1         1        1                   control       ovx        26.00
2         1        2                   control       ovx        24.50
3         1        3                   control       ovx        20.40
4         2        4                   control   hemiovx        26.59
5         2        5                   control       ovx        23.50
6         2        6                      maca       ovx        25.00
7         2        7                      maca       ovx        24.80
8         3        8                      maca       ovx        23.20
9         3        9                      maca   hemiovx        22.69
10        3       10                      maca       ovx        23.90
11        5       11             maca + critro       ovx        21.90
12        5       12             maca + critro       ovx        23.40
13        5       13             maca + critro       ovx        21.90
14        5       14             maca + critro       ovx        22.40
15        8       15 triple dosis maca + citro       ovx        18.90
16        8       16 triple dosis maca + citro       ovx        23.50
17        9       17 triple dosis maca + citro       ovx        24.50
18        9       18 triple dosis maca + citro       ovx        25.30
19        9       19 triple dosis maca + citro       ovx        27.90
20        9       20             sham operated    no ovx        25.50
21       10       21             sham operated    no ovx        23.40
22       10       22             sham operated    no ovx        22.50
23       10       23             sham operated    no ovx        22.90
   peso_final peso_utero    chol glucose    tag prot   urea album
1       33.28      0.089  85.990  109.97 182.42 5.37  66.27 66.82
2       30.50      0.063  94.460   81.62 211.87 4.68  76.73 55.36
3       29.93      0.078  99.670  118.37 195.16   NA  52.32    NA
4       32.19      0.134  83.380   71.91  98.46   NA  50.71    NA
5       30.37      0.052  82.080   95.53 108.13 5.33  26.02    NA
6       30.43      0.055 107.490  160.36 141.10   NA     NA 72.14
7       28.77      0.064  76.870  195.53  95.82 5.02  40.78 67.09
8       27.30      0.062  95.760  182.41 105.49 6.12  66.94 70.64
9       26.86      0.070  85.340  184.51  90.99   NA     NA 66.27
10      29.10      0.113  82.080  168.50 143.30 4.85  34.48 83.73
11      24.93      0.108  80.781  113.38 128.35   NA     NA    NA
12      26.70      0.022  88.590  102.62 282.64   NA     NA    NA
13      28.67      0.014 104.880   60.10 200.00 5.33  37.96    NA
14      28.37      0.046  70.350  150.13 199.12 4.93  45.61 64.64
15      23.80      0.057  78.170  110.50 114.73 4.78  38.23 52.77
16      26.70      0.065  85.340  144.88 134.51 5.15  43.06 59.59
17      28.77      0.016  64.400  138.85 160.44   NA     NA    NA
18      29.20      0.068  67.100  140.68 127.03   NA     NA    NA
19      29.48      0.076  65.790  114.70 169.67 6.17     NA    NA
20      30.27      0.088  74.260   94.23 185.05 4.93     NA 68.59
21      27.90      0.535  59.280  126.77 244.84   NA  60.37    NA
22      26.68      0.081  68.400   78.22  93.19   NA 157.89    NA
23      27.43      0.176  84.690  125.20 108.13   NA     NA    NA
  • ¿Qué pasa si no se sabe si el duplicado es erróneo?

    • Podemos tener dos o más filas con duplicados y no saber cuál es el correcto.

    • En estos casos, el problema es complejo. Una solución puede ser la deduplicación probabilística.

Paso 3: Identifique datos faltantes

  • Evalúe número y porcentaje de datos perdidos así como el patrón de estos.

  • Hay varios paquetes que permiten manejar datos perdidos:

    • {VIM}
    • {visdat}
    • {naniar}
    • {otros}
  • Usaremos algunas funciones de {visdat}, {VIM}y {naniar}.

  • {visdat}y {nanair}generan gráficos {ggplot2}, mientras que {VIM} no lo hace.

Paso 3: Identifique datos faltantes (cont.)

  • Nuevamente skim() nos permite conocer, rápidamente, el número de datos perdidos.
skim(datos)
Data summary
Name datos
Number of rows 23
Number of columns 13
_______________________
Column type frequency:
character 2
numeric 11
________________________
Group variables None

Variable type: character

skim_variable n_missing complete_rate min max empty n_unique whitespace
tratamiento 0 1 4 25 0 5 0
protocolo 0 1 3 7 0 3 0

Variable type: numeric

skim_variable n_missing complete_rate mean sd p0 p25 p50 p75 p100 hist
id_jaula 0 1.00 5.30 3.38 1.00 2.00 5.00 9.00 10.00 ▇▃▅▂▇
id_raton 0 1.00 12.00 6.78 1.00 6.50 12.00 17.50 23.00 ▇▆▇▆▇
peso_inicial 0 1.00 23.68 1.99 18.90 22.59 23.50 24.90 27.90 ▂▃▇▇▂
peso_final 0 1.00 28.59 2.18 23.80 27.08 28.77 30.10 33.28 ▂▆▇▅▂
peso_utero 0 1.00 0.09 0.10 0.01 0.06 0.07 0.09 0.54 ▇▁▁▁▁
chol 0 1.00 81.96 12.89 59.28 72.31 82.08 87.29 107.49 ▅▃▇▃▃
glucose 0 1.00 124.74 37.27 60.10 99.08 118.37 147.50 195.53 ▅▇▇▃▅
tag 0 1.00 153.06 52.36 90.99 108.13 141.10 190.11 282.64 ▇▃▅▁▂
prot 11 0.52 5.22 0.49 4.68 4.91 5.08 5.34 6.17 ▇▃▅▁▃
urea 9 0.61 56.95 32.34 26.02 38.87 48.16 64.80 157.89 ▇▃▁▁▁
album 12 0.48 66.15 8.44 52.77 62.12 66.82 69.62 83.73 ▃▃▇▂▂
  • El paquete {visdat} te permite visualizar el tipo de dato y si hay o no presencia de datos perdidos
library(visdat)
datos %>% 
  vis_dat()

  • Es importante verificar si el tipo de dato corresponde con la naturaleza de la variable de estudio.

  • Algunos datos faltantes pueden no verse por no configurar apropiadamente el tipo de la variable.

  • Podemos también generar gráficos para identificar los datos perdidos y sus combinaciones:
datos %>% 
  vis_miss()

  • Se aprecia que la variable prot tiene 47.83% de sus datos faltantes. La variable urea tiene 39.13% de sus datos faltantes.

  • La legenda que dice Missing (10.7%) indica que el total de datos faltantes en las celdas (no en las filas) es de 10.7%.

  • ¿Cuántos datos faltantes en por fila tendremos? ¿Qué combinaciones de datos faltantes tendremos?

Paso 3: Identifique datos faltantes (cont.)

  • El paquete {VIM} permite identificar datos perdidos por variable y sus combinaciones.

  • Podemos visualizar los resultados directamente con la función aggr():

library(VIM)
datos %>% 
  aggr(numbers = TRUE)

  • También podemos usar la función gg_miss_upset del paquete {naniar} para evaluar las combinaciones de datos perdidos:
library(naniar)
datos %>% 
  gg_miss_upset()

  • Lo primero que uno debe tratar de hacer es recuperar los datos faltantes.

    • Volver a revisar documentos fuentes.

    • Recontactar sujetos, etc.

  • Podemos identificar a los individuos con datos faltantes en la variable urea usando filter():

datos %>% 
  select(id_jaula, id_raton, urea) %>% 
  filter(is.na(urea))
  id_jaula id_raton urea
1        2        6   NA
2        3        9   NA
3        5       11   NA
4        5       12   NA
5        9       17   NA
6        9       18   NA
7        9       19   NA
8        9       20   NA
9       10       23   NA
  • Si se recupera la información, uno puede remplazar los valores usando código en R.

  • La función replace()del paquete {dplyr} es útil para esto. Supongamos que el dato perdido para el ratón 6 es de 65.2, podemos rempalzar el dato usando replace()

datos %>% 
  select(id_jaula, id_raton, urea) %>% 
  mutate(
    urea = replace(urea, id_raton == 6, 65.2)
  )
   id_jaula id_raton   urea
1         1        1  66.27
2         1        2  76.73
3         1        3  52.32
4         2        4  50.71
5         2        5  26.02
6         2        6  65.20
7         2        7  40.78
8         3        8  66.94
9         3        9     NA
10        3       10  34.48
11        5       11     NA
12        5       12     NA
13        5       13  37.96
14        5       14  45.61
15        8       15  38.23
16        8       16  43.06
17        9       17     NA
18        9       18     NA
19        9       19     NA
20        9       20     NA
21       10       21  60.37
22       10       22 157.89
23       10       23     NA
  • Los datos perdidos a veces se guardan por defecto con algunos caracteres especiales.

  • Pueden ser problemáticas si se guardan con categorías como: -99, 8888, “No aplica”, “No sabe”, etc.

  • Una función muy útil para lidiar con estos datos y convertirlos en NA es la función replace_na()del paquete {tidyr}

library(tidyr)
datos_perdidos_comun
   edad diabetes
1    45       Sí
2    23       Sí
3    34       No
4    29      N/A
5  -999       No
6    23       Sí
7    34       No
8    57      N/A
9    88      N/A
10 -999      N/A
11 -999       Sí
  • Podemos convertir directamente todos estos valores por default a datos perdidos:
datos_perdidos_comun %>% 
  na_if(list(edad = -999, diabetes = "N/A")) -> datos_perdidos_limpia

datos_perdidos_limpia
   edad diabetes
1    45       Sí
2    23       Sí
3    34       No
4    29     <NA>
5    NA       No
6    23       Sí
7    34       No
8    57     <NA>
9    88     <NA>
10   NA     <NA>
11   NA       Sí

Paso 4: Identifique valores extremos no plausibles

  • Revise, variable por variable valores extremos no plausibles o plausibles, pero sospechosamente extremos. El valor mínimo es p0 y el valor máximo es p100. Deben ser plausibles.
skim(datos)
Data summary
Name datos
Number of rows 23
Number of columns 13
_______________________
Column type frequency:
character 2
numeric 11
________________________
Group variables None

Variable type: character

skim_variable n_missing complete_rate min max empty n_unique whitespace
tratamiento 0 1 4 25 0 5 0
protocolo 0 1 3 7 0 3 0

Variable type: numeric

skim_variable n_missing complete_rate mean sd p0 p25 p50 p75 p100 hist
id_jaula 0 1.00 5.30 3.38 1.00 2.00 5.00 9.00 10.00 ▇▃▅▂▇
id_raton 0 1.00 12.00 6.78 1.00 6.50 12.00 17.50 23.00 ▇▆▇▆▇
peso_inicial 0 1.00 23.68 1.99 18.90 22.59 23.50 24.90 27.90 ▂▃▇▇▂
peso_final 0 1.00 28.59 2.18 23.80 27.08 28.77 30.10 33.28 ▂▆▇▅▂
peso_utero 0 1.00 0.09 0.10 0.01 0.06 0.07 0.09 0.54 ▇▁▁▁▁
chol 0 1.00 81.96 12.89 59.28 72.31 82.08 87.29 107.49 ▅▃▇▃▃
glucose 0 1.00 124.74 37.27 60.10 99.08 118.37 147.50 195.53 ▅▇▇▃▅
tag 0 1.00 153.06 52.36 90.99 108.13 141.10 190.11 282.64 ▇▃▅▁▂
prot 11 0.52 5.22 0.49 4.68 4.91 5.08 5.34 6.17 ▇▃▅▁▃
urea 9 0.61 56.95 32.34 26.02 38.87 48.16 64.80 157.89 ▇▃▁▁▁
album 12 0.48 66.15 8.44 52.77 62.12 66.82 69.62 83.73 ▃▃▇▂▂
  • Permite hacer algo similar
describe(datos)
datos 

 13  Variables      23  Observations
--------------------------------------------------------------------------------
id_jaula 
       n  missing distinct     Info     Mean      Gmd 
      23        0        7    0.979    5.304    3.881 

lowest :  1  2  3  5  8, highest:  3  5  8  9 10
                                                    
Value          1     2     3     5     8     9    10
Frequency      3     4     3     4     2     4     3
Proportion 0.130 0.174 0.130 0.174 0.087 0.174 0.130
--------------------------------------------------------------------------------
id_raton 
       n  missing distinct     Info     Mean      Gmd      .05      .10 
      23        0       23        1       12        8      2.1      3.2 
     .25      .50      .75      .90      .95 
     6.5     12.0     17.5     20.8     21.9 

lowest :  1  2  3  4  5, highest: 19 20 21 22 23
--------------------------------------------------------------------------------
tratamiento 
       n  missing distinct 
      23        0        5 

lowest : control                   maca                      maca + critro             sham operated             triple dosis maca + citro
highest: control                   maca                      maca + critro             sham operated             triple dosis maca + citro

control (5, 0.217), maca (5, 0.217), maca + critro (4, 0.174), sham operated
(4, 0.174), triple dosis maca + citro (5, 0.217)
--------------------------------------------------------------------------------
protocolo 
       n  missing distinct 
      23        0        3 
                                  
Value      hemiovx  no ovx     ovx
Frequency        2       4      17
Proportion   0.087   0.174   0.739
--------------------------------------------------------------------------------
peso_inicial 
       n  missing distinct     Info     Mean      Gmd      .05      .10 
      23        0       19    0.998    23.68    2.244    20.55    21.90 
     .25      .50      .75      .90      .95 
   22.59    23.50    24.90    25.90    26.53 

lowest : 18.90 20.40 21.90 22.40 22.50, highest: 25.30 25.50 26.00 26.59 27.90
                                                                            
Value      18.90 20.40 21.90 22.40 22.50 22.69 22.90 23.20 23.40 23.50 23.90
Frequency      1     1     2     1     1     1     1     1     2     2     1
Proportion 0.043 0.043 0.087 0.043 0.043 0.043 0.043 0.043 0.087 0.087 0.043
                                                          
Value      24.50 24.80 25.00 25.30 25.50 26.00 26.59 27.90
Frequency      2     1     1     1     1     1     1     1
Proportion 0.087 0.043 0.043 0.043 0.043 0.043 0.043 0.043
--------------------------------------------------------------------------------
peso_final 
       n  missing distinct     Info     Mean      Gmd      .05      .10 
      23        0       21    0.999    28.59    2.483    25.11    26.68 
     .25      .50      .75      .90      .95 
   27.08    28.77    30.10    30.49    32.02 

lowest : 23.80 24.93 26.68 26.70 26.86, highest: 30.37 30.43 30.50 32.19 33.28
--------------------------------------------------------------------------------
peso_utero 
       n  missing distinct     Info     Mean      Gmd      .05      .10 
      23        0       23        1   0.0927  0.07728   0.0166   0.0268 
     .25      .50      .75      .90      .95 
  0.0560   0.0680   0.0885   0.1298   0.1718 

lowest : 0.014 0.016 0.022 0.046 0.052, highest: 0.108 0.113 0.134 0.176 0.535
--------------------------------------------------------------------------------
chol 
       n  missing distinct     Info     Mean      Gmd      .05      .10 
      23        0       21    0.999    81.96     14.9    64.54    66.05 
     .25      .50      .75      .90      .95 
   72.31    82.08    87.29    98.89   104.36 

lowest :  59.28  64.40  65.79  67.10  68.40, highest:  94.46  95.76  99.67 104.88 107.49
--------------------------------------------------------------------------------
glucose 
       n  missing distinct     Info     Mean      Gmd      .05      .10 
      23        0       23        1    124.7    43.44    72.54    78.90 
     .25      .50      .75      .90      .95 
   99.08   118.37   147.50   179.63   184.30 

lowest :  60.10  71.91  78.22  81.62  94.23, highest: 160.36 168.50 182.41 184.51 195.53
--------------------------------------------------------------------------------
tag 
       n  missing distinct     Info     Mean      Gmd      .05      .10 
      23        0       22        1    153.1    59.41    93.45    96.35 
     .25      .50      .75      .90      .95 
  108.13   141.10   190.11   209.50   241.54 

lowest :  90.99  93.19  95.82  98.46 105.49, highest: 199.12 200.00 211.87 244.84 282.64
--------------------------------------------------------------------------------
prot 
       n  missing distinct     Info     Mean      Gmd      .05      .10 
      12       11       10    0.993    5.222   0.5367    4.735    4.787 
     .25      .50      .75      .90      .95 
   4.910    5.085    5.340    6.045    6.143 

lowest : 4.68 4.78 4.85 4.93 5.02, highest: 5.15 5.33 5.37 6.12 6.17
                                                                      
Value       4.68  4.78  4.85  4.93  5.02  5.15  5.33  5.37  6.12  6.17
Frequency      1     1     1     2     1     1     2     1     1     1
Proportion 0.083 0.083 0.083 0.167 0.083 0.083 0.167 0.083 0.083 0.083
--------------------------------------------------------------------------------
urea 
       n  missing distinct     Info     Mean      Gmd      .05      .10 
      14        9       14        1    56.95    30.41    31.52    35.52 
     .25      .50      .75      .90      .95 
   38.87    48.16    64.80    73.79   105.14 

lowest :  26.02  34.48  37.96  38.23  40.78, highest:  60.37  66.27  66.94  76.73 157.89
                                                                         
Value       26.02  34.48  37.96  38.23  40.78  43.06  45.61  50.71  52.32
Frequency       1      1      1      1      1      1      1      1      1
Proportion  0.071  0.071  0.071  0.071  0.071  0.071  0.071  0.071  0.071
                                             
Value       60.37  66.27  66.94  76.73 157.89
Frequency       1      1      1      1      1
Proportion  0.071  0.071  0.071  0.071  0.071
--------------------------------------------------------------------------------
album 
       n  missing distinct     Info     Mean      Gmd      .05      .10 
      11       12       11        1    66.15    9.592    54.06    55.36 
     .25      .50      .75      .90      .95 
   62.12    66.82    69.62    72.14    77.94 

lowest : 52.77 55.36 59.59 64.64 66.27, highest: 67.09 68.59 70.64 72.14 83.73
                                                                            
Value      52.77 55.36 59.59 64.64 66.27 66.82 67.09 68.59 70.64 72.14 83.73
Frequency      1     1     1     1     1     1     1     1     1     1     1
Proportion 0.091 0.091 0.091 0.091 0.091 0.091 0.091 0.091 0.091 0.091 0.091
--------------------------------------------------------------------------------
  • El gráfico de cajas nos muestra la disrtibución de la variable numérica en termino de sus cuantiles.

  • Los puntos aislados, fuera de las cajas y bigotes, son considerados valores extremos.

  • Estos pueden ser plausibles o no plausibles.

  • El gráfico de cajas permite identificar, rápidamente, valores extremos potencialmente no plausibles o problemáticos.

boxplot(datos$peso_final)

boxplot(datos$peso_utero)

  • Los datos extremos pueden ser valores anómalos válidos.

  • En ocasiones, son valores no plausibles, inválidos, producto del mal recojo de información.

  • Cuando se tenga valores extremos no plausibles se puede optar por dos acciones:

      1. Corregir el valor extremo no plausible por datos que sí sean plausibles.
      1. Si no se puede, convertir los valores extremos no plausibles en datos faltantes (veremos esto).
      1. Bonus: A veces puede ser mejor recortar los datos y quedarse con el 1% y 99% percentil más bajo y alto, respectivamente.

Paso 4: Identifique valores extremos no plausibles

  • Se puede usar la función: na_if() del paquete {dplyr}.
  • Veamos una base de datos juguete con datos de peso (kg) y hemoglobina (mg/dL) de pacientes en un estudio:

    • El peso de 1450 es un valor extremo no plausible. Igualmente, los valores de hemoglobina 213, 3124 y -4 son valores extremos no plausibles.

    • Lo primero que debemos hacer es recuperar es tratar de recuperar estos valores.

    • Supongamos que podemos recuperar los valores: 1450 en realidad es 45 kg; 213, 3124 y -4 son 11.3, 10.44 y 9.2 mg/dL.

  • Podemos usar la función recode para corregir los valores de peso:

datos_extremo %>% 
  mutate(peso = recode(peso, `1450` = 45))
  peso   hb
1   56   12
2   34   11
3   23  213
4   78   10
5   46 3124
6   45   -4
  • También podemos corregir de varias variables simultáneamente:
datos_extremo %>% 
  mutate(
    peso = recode(peso, `1450` = 45), 
    hb = recode(hb, `213` = 11.3, `3124` = 10.44, `-4` = 9.2)
    ) -> datos_extremo_recodif

datos_extremo_recodif
  peso    hb
1   56 12.00
2   34 11.00
3   23 11.30
4   78 10.00
5   46 10.44
6   45  9.20
  • Si no podemos recuperar los datos correctos, la otra opción es convertir los valores extremos en datos faltantes:
datos_extremo %>% 
  mutate(
    peso = na_if(peso, 1450)
  )
  peso   hb
1   56   12
2   34   11
3   23  213
4   78   10
5   46 3124
6   NA   -4
  • Podemos hacerlo de manera simultánea para varias variables
datos_extremo %>% 
  mutate(
    peso = na_if(peso, 1450), 
    hb = na_if(hb, 213), 
    hb = na_if(hb, 3124), 
    hb = na_if(hb, -4)
  )
  peso hb
1   56 12
2   34 11
3   23 NA
4   78 10
5   46 NA
6   NA NA
  • O usando replace() y una condición lógica:
datos_extremo %>% 
  mutate(
    peso = na_if(peso, 1450), 
    hb = replace(hb, hb > 100 | hb < 0, NA)
  ) -> datos_extremo_recomiss

datos_extremo_recomiss
  peso hb
1   56 12
2   34 11
3   23 NA
4   78 10
5   46 NA
6   NA NA

Paso 5: Detecte y corrija inconsistencias mediante consultas (queries) de interés

Muestre el peso inicial mínimo, máximo y promedio del grupo control:

datos %>% 
  filter(tratamiento == "control") %>% 
  summarise(
    minimo_peso = min(peso_inicial), 
    maximo_peso = max(peso_inicial), 
    promedio_peso = mean(peso_inicial)
  )
  minimo_peso maximo_peso promedio_peso
1        20.4       26.59        24.198

Muestre los pesos inicial máximos, mínimo y promedio según grupo de tratamiento. También muestre el número de ratones por grupo:

datos %>% 
  group_by(tratamiento) %>% 
  summarise(
    minimo_peso = min(peso_inicial), 
    maximo_peso = max(peso_inicial), 
    promedio_peso = mean(peso_inicial), 
    n_ratones = n()
  )
# A tibble: 5 × 5
  tratamiento               minimo_peso maximo_peso promedio_peso n_ratones
  <chr>                           <dbl>       <dbl>         <dbl>     <int>
1 control                          20.4        26.6          24.2         5
2 maca                             22.7        25            23.9         5
3 maca + critro                    21.9        23.4          22.4         4
4 sham operated                    22.5        25.5          23.6         4
5 triple dosis maca + citro        18.9        27.9          24.0         5

Muestre los id_jaula con el número de ratones por jaula

datos %>% 
  group_by(id_jaula) %>% 
  summarise(n_ratones_por_jaula = n())
# A tibble: 7 × 2
  id_jaula n_ratones_por_jaula
     <int>               <int>
1        1                   3
2        2                   4
3        3                   3
4        5                   4
5        8                   2
6        9                   4
7       10                   3

Identifique los ID de los ratones del grupo control con una razón glucosa / colesterol > 1

datos %>% 
  filter(tratamiento == "control" & glucose / chol > 1)
  id_jaula id_raton tratamiento protocolo peso_inicial peso_final peso_utero
1        1        1     control       ovx         26.0      33.28      0.089
2        1        3     control       ovx         20.4      29.93      0.078
3        2        5     control       ovx         23.5      30.37      0.052
   chol glucose    tag prot  urea album
1 85.99  109.97 182.42 5.37 66.27 66.82
2 99.67  118.37 195.16   NA 52.32    NA
3 82.08   95.53 108.13 5.33 26.02    NA

Otra forma de hacerlo, es crear primerio la razón glucose / chol y filtrar:

datos %>% 
  mutate(ratio_gluc_chol = glucose / chol) %>% 
  filter(tratamiento == "control" & ratio_gluc_chol > 1)
  id_jaula id_raton tratamiento protocolo peso_inicial peso_final peso_utero
1        1        1     control       ovx         26.0      33.28      0.089
2        1        3     control       ovx         20.4      29.93      0.078
3        2        5     control       ovx         23.5      30.37      0.052
   chol glucose    tag prot  urea album ratio_gluc_chol
1 85.99  109.97 182.42 5.37 66.27 66.82        1.278870
2 99.67  118.37 195.16   NA 52.32    NA        1.187619
3 82.08   95.53 108.13 5.33 26.02    NA        1.163865

Nuestro turno



  • Haga el análisis inicial de datos con los datos gapminder.



 

Medidas de resumen para variables numéricas

Medidas de resumen para variables numéricas

Medidas de resumen en R base

Funciones

  • Funciones de R base:

    • mean()

    • mean(…, trim = …)

    • median()

  • Funciones extras a R base:

    • geometric.mean() de {psych}

Datos para los cálculos

  • Sean el vector de edades:
edad <- c(9, 12, 10, 8, 7, 6)
edad
[1]  9 12 10  8  7  6
  • Sea el vector de hemoglobina:
hb <- c(11.2, 10.4, 9.8, NA, 14, 8.1)
hb
[1] 11.2 10.4  9.8   NA 14.0  8.1

Media aritmética

  • En vector con datos completos:
mean(edad)
[1] 8.666667
  • En vector con datos incompletos:
mean(hb)
[1] NA
  • Es necesario agregar na.rm = TRUE
mean(hb, na.rm = TRUE)
[1] 10.7

Media geométrica

  • Manualemente
exp(log(edad))
[1]  9 12 10  8  7  6
  • Con librería psych
library(psych)
geometric.mean(edad)
[1] 8.445535

Media truncada

  • Solo 5% de ambas colas
mean(edad, trim = 0.05)
[1] 8.666667

Mediana

median(hb, na.rm = TRUE)
[1] 10.4

Funciones

  • Funciones de R base:

    • quantile(…, probs = …)

Datos para los cálculos

  • Sean el vector de edades:
edad <- c(9, 12, 10, 8, 7, 6)
edad
[1]  9 12 10  8  7  6
  • Sea el vector de hemoglobina:
hb <- c(11.2, 10.4, 9.8, NA, 14, 8.1)
hb
[1] 11.2 10.4  9.8   NA 14.0  8.1

Cuartiles

  • Cuartil 1 (25%)
quantile(edad, probs = c(0.25))
 25% 
7.25 
  • Cuartil 3 (75%)
quantile(edad, probs = c(0.75))
 75% 
9.75 
  • Cuartiles 1, 2 y 3
quantile(edad, probs = c(0.25, 0.5, 0.75))
 25%  50%  75% 
7.25 8.50 9.75 

Percentiles

  • Percentil 67
quantile(edad, probs = c(0.67))
 67% 
9.35 
  • Percentiles del 1 al 99
quantile(edad, probs = seq(0, 0.99, 0.01))
   0%    1%    2%    3%    4%    5%    6%    7%    8%    9%   10%   11%   12% 
 6.00  6.05  6.10  6.15  6.20  6.25  6.30  6.35  6.40  6.45  6.50  6.55  6.60 
  13%   14%   15%   16%   17%   18%   19%   20%   21%   22%   23%   24%   25% 
 6.65  6.70  6.75  6.80  6.85  6.90  6.95  7.00  7.05  7.10  7.15  7.20  7.25 
  26%   27%   28%   29%   30%   31%   32%   33%   34%   35%   36%   37%   38% 
 7.30  7.35  7.40  7.45  7.50  7.55  7.60  7.65  7.70  7.75  7.80  7.85  7.90 
  39%   40%   41%   42%   43%   44%   45%   46%   47%   48%   49%   50%   51% 
 7.95  8.00  8.05  8.10  8.15  8.20  8.25  8.30  8.35  8.40  8.45  8.50  8.55 
  52%   53%   54%   55%   56%   57%   58%   59%   60%   61%   62%   63%   64% 
 8.60  8.65  8.70  8.75  8.80  8.85  8.90  8.95  9.00  9.05  9.10  9.15  9.20 
  65%   66%   67%   68%   69%   70%   71%   72%   73%   74%   75%   76%   77% 
 9.25  9.30  9.35  9.40  9.45  9.50  9.55  9.60  9.65  9.70  9.75  9.80  9.85 
  78%   79%   80%   81%   82%   83%   84%   85%   86%   87%   88%   89%   90% 
 9.90  9.95 10.00 10.10 10.20 10.30 10.40 10.50 10.60 10.70 10.80 10.90 11.00 
  91%   92%   93%   94%   95%   96%   97%   98%   99% 
11.10 11.20 11.30 11.40 11.50 11.60 11.70 11.80 11.90 

Varianza muestral

  • Con datos completos:
var(edad)
[1] 4.666667
  • Con datos perdidos:
var(hb, na.rm = TRUE)
[1] 4.7

Desviación estándar muestral

  • Con datos completos:
sd(edad)
[1] 2.160247
  • Con datos faltantes:
sd(hb, na.rm = TRUE)
[1] 2.167948

Manualmente

  • Con datos completos:
min(edad)
[1] 6
max(edad)
[1] 12
max(edad) - min(edad)
[1] 6

Usando función

  • Con datos completos:
range(edad)
[1]  6 12
  • Con datos faltantes:
range(hb, na.rm = TRUE)
[1]  8.1 14.0

Manualmente

  • Calculándolo manualmente
quantile(edad, probs = c(0.25, 0.75))
 25%  75% 
7.25 9.75 
9.75 - 7.25
[1] 2.5
  • Usando algunos atajos:

Podemos almacenar los resultados en objetos

p25 <- quantile(edad, probs = c(0.25))
p25
 25% 
7.25 
p75 <- quantile(edad, probs = c(0.75))
p75
 75% 
9.75 

Luego podemos usar los objetos par hacer el cálculo final:

p75 - p25
75% 
2.5 

Usando función

  • Con datos completos:
IQR(edad)
[1] 2.5
  • Con datos faltantes:
IQR(hb, na.rm = TRUE)
[1] 1.4

Análisis de varias variables numéricas

  • Hay varias opciones en R.

  • Las más personalizables se basan en {R base} y {dplyr} (funciones summarise()), pero requieren más código.

    • Usar estas si se necesitan elaborar tablas ad hoc para reportes repropducibles muy sui generis.

    • También son necesarias para gráficos en {ggplot2}

  • Las opciones que requieren poco código y son directas tienen el problema de que no son personalizables:

    • {summarytools}

    • {DescTools}

    • {Hmisc}

    • Usar estas si solo se requiere inspeccionar los datos pero no se hará ningún reporte reproducibl sui generis.

  • El problema con R base es que solo permite generar medidas de resumen una a la vez.

  • Cuando inspeccionamos datos o los describimos necesitamos hacerlo con varias variables simultáneamnente.

  • Podemos hacerlo con otras funciones de R.

  • Hay muchas opciones, veremos algunas que se sustentan en R tidy

  • Podemos usar la función summarise() para solicitar estadísticos de resumen. Se requiere llamar las funciones de R base para medidas de resumen.

Sin etiquetado

bd_inmuno %>% 
  summarise(mean(edad))
  mean(edad)
1   48.24561

Mejor con etiquetado

bd_inmuno %>% 
  summarise(Media = mean(edad))
     Media
1 48.24561

Varios estadísticos pueden obtenerse

bd_inmuno %>% 
  summarise(
    Media = mean(edad), 
    DE = sd(edad), 
    Mediana = median(edad), 
    `Percentil 25` = quantile(edad, 0.25), 
    `Percentil 75` = quantile(edad, 0.75) 
    )
     Media       DE Mediana Percentil 25 Percentil 75
1 48.24561 14.70901      46           36           59

Varias variables pueden analizarse

bd_inmuno %>% 
  summarise(
    `Media de edad` = mean(edad), 
    Mediana_IgG_Final = median(IgG_Basal, na.rm = TRUE), 
    RIQ_IgG_Final = IQR(IgG_Basal, na.rm = TRUE)
    )
  Media de edad Mediana_IgG_Final RIQ_IgG_Final
1      48.24561            28.325         88.17
  • Genera un resumen descriptivo bastante detallado de las variables numéricas.
library(summarytools)
bd_inmuno2 <- bd_inmuno %>% 
  select(-tdosis_refuerzo)
  • La función que describe variables numéricas es descr()

Una sola variable numérica

bd_inmuno2 %>% 
  descr(edad)
Descriptive Statistics  
bd_inmuno2$edad  
Label: edad  
N: 285  

                      edad
----------------- --------
             Mean    48.25
          Std.Dev    14.71
              Min    23.00
               Q1    36.00
           Median    46.00
               Q3    59.00
              Max    97.00
              MAD    17.79
              IQR    23.00
               CV     0.30
         Skewness     0.44
      SE.Skewness     0.14
         Kurtosis    -0.39
          N.Valid   285.00
        Pct.Valid   100.00

Todas las variables numéricas

bd_inmuno2 %>% 
  descr()
Descriptive Statistics  
bd_inmuno2  
N: 285  

                      edad       id   IgG_Basal   IgG_Final
----------------- -------- -------- ----------- -----------
             Mean    48.25   143.00       82.54      492.26
          Std.Dev    14.71    82.42      122.33       71.15
              Min    23.00     1.00       -2.19      235.51
               Q1    36.00    72.00        8.13      447.18
           Median    46.00   143.00       28.33      501.20
               Q3    59.00   214.00       96.61      545.15
              Max    97.00   285.00      583.97      618.44
              MAD    17.79   105.26       36.80       70.13
              IQR    23.00   142.00       88.17       97.97
               CV     0.30     0.58        1.48        0.14
         Skewness     0.44     0.00        2.14       -0.73
      SE.Skewness     0.14     0.14        0.14        0.14
         Kurtosis    -0.39    -1.21        3.92        0.44
          N.Valid   285.00   285.00      284.00      285.00
        Pct.Valid   100.00   100.00       99.65      100.00

Solo algunas variables numéricas

bd_inmuno2 %>% 
  select(edad, IgG_Basal) %>% 
  descr()
Descriptive Statistics  
bd_inmuno2  
N: 285  

                      edad   IgG_Basal
----------------- -------- -----------
             Mean    48.25       82.54
          Std.Dev    14.71      122.33
              Min    23.00       -2.19
               Q1    36.00        8.13
           Median    46.00       28.33
               Q3    59.00       96.61
              Max    97.00      583.97
              MAD    17.79       36.80
              IQR    23.00       88.17
               CV     0.30        1.48
         Skewness     0.44        2.14
      SE.Skewness     0.14        0.14
         Kurtosis    -0.39        3.92
          N.Valid   285.00      284.00
        Pct.Valid   100.00       99.65

Solo algunos estadísticos

bd_inmuno2 %>% 
  descr(edad, 
        stats = c("mean", "sd", "min", "max"))
Descriptive Statistics  
bd_inmuno2$edad  
Label: edad  
N: 285  

                 edad
------------- -------
         Mean   48.25
      Std.Dev   14.71
          Min   23.00
          Max   97.00
  • El paquete {Hmisc} genera un reporte de resultados similar al de summarytools.
library(Hmisc)
  • La función describe() del paquete {Hmisc} genera un reporte con los principales estadísticos de resumen:

Modo R base

describe(bd_inmuno$edad)
   vars   n  mean    sd median trimmed   mad min max range skew kurtosis   se
X1    1 285 48.25 14.71     46   47.55 17.79  23  97    74 0.44    -0.39 0.87
bd_inmuno %>% 
  pull(edad) %>% 
  describe()
   vars   n  mean    sd median trimmed   mad min max range skew kurtosis   se
X1    1 285 48.25 14.71     46   47.55 17.79  23  97    74 0.44    -0.39 0.87

Nuestro turno



  • Con los datos de gapminder, realice algunos análisis descriptivos.



 

Hagamos una pausa


Tomemos un descanso de 5 minutos

Estire las piernas

Deje de ver las pantallas

… cualquier , las del celular también.

05:00

Medidas de resumen de variables categóricas con R

Medidas de resumen de variables categóricas con R

Análisis con R

  • Hay varias opciones en R.

  • Las más personalizables se basan en {dplyr} y {janitor} (funciones summarise()), pero requieren más código.

    • Usar estas si se necesitan elaborar tablas ad hoc para reportes repropducibles muy sui generis.

    • También son necesarias para gráficos en {ggplot2}

  • Las opciones que requieren poco código y son directas tienen el problema de que no son personalizables:

    • {summarytools}

    • {DescTools}

    • Usar estas si solo se requiere inspeccionar los datos pero no se hará ningún reporte reproducibl sui generis.

La función table() y prop.table()es la más usada. Sin embargo, genera tablas “sucias” que requieren mucho código para personalizarse.

  • Tabla de frecuencias absolutas
table(bd_inmuno$sexo)

 Femenino Masculino 
      189        95 
  • Tabla de frecuencias relativas
prop.table(table(bd_inmuno$sexo))

 Femenino Masculino 
 0.665493  0.334507 
  • Tabla de frecuencias incluyendo los datos faltantes
table(bd_inmuno$sexo, useNA = "always")

 Femenino Masculino      <NA> 
      189        95         1 

Podemos combinar la funcion group_by() con summarise() para generar una tabla de frecuencias de la variable de interés. Podemos también tomar un atajo con count

  • Frecuencias absolutas: Forma larga
bd_inmuno %>% 
  group_by(sexo) %>% 
  summarise(n = n())
# A tibble: 3 × 2
  sexo          n
  <chr>     <int>
1 Femenino    189
2 Masculino    95
3 <NA>          1
  • Frecuencias absolutas + relativas: Forma larga
library(scales) # Para agregar escalas, p. ej., porcentajes %
bd_inmuno %>% 
  group_by(sexo) %>% 
  summarise(n = n()) %>% 
  mutate(
    Porcentaje = scales::percent(n / sum(n))
  )
# A tibble: 3 × 3
  sexo          n Porcentaje
  <chr>     <int> <chr>     
1 Femenino    189 66%       
2 Masculino    95 33%       
3 <NA>          1 0%        
  • Frecuencias absolutas: Atajo con count()
bd_inmuno %>% 
  count(sexo)
       sexo   n
1  Femenino 189
2 Masculino  95
3      <NA>   1
  • Frecuencias absolutas + relativas: Atajo con count()
library(scales) # Para agregar escalas, p. ej., porcentajes %
bd_inmuno %>% 
  count(sexo) %>% 
  mutate(
    Porcentaje = scales::percent(n / sum(n))
  )
       sexo   n Porcentaje
1  Femenino 189        66%
2 Masculino  95        33%
3      <NA>   1         0%

El paquete {janitor}, a través de su función [tabyl(){.verde-h3}], ofrece atajos y funciones pre-definidas para realizar tablas basadas en funciones de {dplyr}.

  • {janitor} ejecuta internamente summarise(), group_by() y otras funciones más, simplificando notoriamente el código.
  • Hay que instalar el paquete {janitor} y luego cargarlo
library(janitor)

Tabla simple generada por tabyl()

bd_inmuno %>% 
  tabyl(sexo)
      sexo   n     percent valid_percent
  Femenino 189 0.663157895      0.665493
 Masculino  95 0.333333333      0.334507
      <NA>   1 0.003508772            NA

Puedes “adornar” la tabla usando más funciones de {janitor}

Cambiar formato de porcentaje a %

bd_inmuno %>% 
  tabyl(sexo, show_na = FALSE) %>% 
  adorn_pct_formatting()
      sexo   n percent
  Femenino 189   66.5%
 Masculino  95   33.5%
  • Puedes suprimir los datos perdidos
bd_inmuno %>% 
  tabyl(sexo, show_na = FALSE)
      sexo   n  percent
  Femenino 189 0.665493
 Masculino  95 0.334507

Agregar totales

bd_inmuno %>% 
  tabyl(sexo, show_na = FALSE) %>% 
  adorn_pct_formatting() %>% 
  adorn_totals()
      sexo   n percent
  Femenino 189   66.5%
 Masculino  95   33.5%
     Total 284       -

Configurar precisión decimal

bd_inmuno %>% 
  tabyl(sexo, show_na = FALSE) %>% 
  adorn_pct_formatting(digits = 2) %>% 
  adorn_totals() 
      sexo   n percent
  Femenino 189  66.55%
 Masculino  95  33.45%
     Total 284       -

Si queremos una evaluación rápida de varias variables puede ser obtenida usando la función freq() del paquete {summarytools}

  • Una sola variable:
bd_inmuno %>% 
  select(sexo) %>% 
  freq()
Frequencies  
bd_inmuno$sexo  
Label: genero  
Type: Character  

                  Freq   % Valid   % Valid Cum.   % Total   % Total Cum.
--------------- ------ --------- -------------- --------- --------------
       Femenino    189     66.55          66.55     66.32          66.32
      Masculino     95     33.45         100.00     33.33          99.65
           <NA>      1                               0.35         100.00
          Total    285    100.00         100.00    100.00         100.00
  • Solo las seleccioandas
bd_inmuno %>% 
  select(sexo, comorb) %>% 
  freq()
Frequencies  
bd_inmuno$sexo  
Label: genero  
Type: Character  

                  Freq   % Valid   % Valid Cum.   % Total   % Total Cum.
--------------- ------ --------- -------------- --------- --------------
       Femenino    189     66.55          66.55     66.32          66.32
      Masculino     95     33.45         100.00     33.33          99.65
           <NA>      1                               0.35         100.00
          Total    285    100.00         100.00    100.00         100.00

bd_inmuno$comorb  
Label: comorbilidad  
Type: Character  

              Freq   % Valid   % Valid Cum.   % Total   % Total Cum.
----------- ------ --------- -------------- --------- --------------
         No    214     75.09          75.09     75.09          75.09
         Sí     71     24.91         100.00     24.91         100.00
       <NA>      0                               0.00         100.00
      Total    285    100.00         100.00    100.00         100.00
  • Todas las variables categóricas
bd_inmuno %>% 
   freq()
Frequencies  
bd_inmuno$sexo  
Label: genero  
Type: Character  

                  Freq   % Valid   % Valid Cum.   % Total   % Total Cum.
--------------- ------ --------- -------------- --------- --------------
       Femenino    189     66.55          66.55     66.32          66.32
      Masculino     95     33.45         100.00     33.33          99.65
           <NA>      1                               0.35         100.00
          Total    285    100.00         100.00    100.00         100.00

bd_inmuno$comorb  
Label: comorbilidad  
Type: Character  

              Freq   % Valid   % Valid Cum.   % Total   % Total Cum.
----------- ------ --------- -------------- --------- --------------
         No    214     75.09          75.09     75.09          75.09
         Sí     71     24.91         100.00     24.91         100.00
       <NA>      0                               0.00         100.00
      Total    285    100.00         100.00    100.00         100.00

bd_inmuno$tipo_refuerzo  
Label: tipo_refuerzo  
Type: Character  

                       Freq   % Valid   % Valid Cum.   % Total   % Total Cum.
-------------------- ------ --------- -------------- --------- --------------
      (Empty string)      1      0.35           0.35      0.35           0.35
          Heterologo    228     80.00          80.35     80.00          80.35
            Homologo     56     19.65         100.00     19.65         100.00
                <NA>      0                               0.00         100.00
               Total    285    100.00         100.00    100.00         100.00

bd_inmuno$ant_COV  
Label: ant_COV  
Type: Character  

                        Freq   % Valid   % Valid Cum.   % Total   % Total Cum.
--------------------- ------ --------- -------------- --------- --------------
         No Infection    201     70.53          70.53     70.53          70.53
      Prior Infection     84     29.47         100.00     29.47         100.00
                 <NA>      0                               0.00         100.00
                Total    285    100.00         100.00    100.00         100.00
  • Eliminando los datos perdidos y otras caracteristicas:
bd_inmuno %>% 
   freq(report.nas = FALSE, 
        totals = FALSE,
        cumul = FALSE, 
        headings= FALSE)
bd_inmuno$sexo  

                  Freq       %
--------------- ------ -------
       Femenino    189   66.55
      Masculino     95   33.45

bd_inmuno$comorb  

           Freq       %
-------- ------ -------
      No    214   75.09
      Sí     71   24.91

bd_inmuno$tipo_refuerzo  

                       Freq       %
-------------------- ------ -------
      (Empty string)      1    0.35
          Heterologo    228   80.00
            Homologo     56   19.65

bd_inmuno$ant_COV  

                        Freq       %
--------------------- ------ -------
         No Infection    201   70.53
      Prior Infection     84   29.47

Reporte Reproducible

Reporte Reproducible

¿Cómo hacer que un análisis de datos sea reproducible?

  • No cree la tabla “manualmente”.

  • Genere las tablas con código:

    • Es reproducible.
    • Menos propenso a error de digitación o lapsus calamis.
    • Han habido retracciones de ensayos clínicos por errores de tipeo!!
    • Es más rápido, ahorrarás tiempo!!

Tablas descriptivas

  • En un artículo estas pueden variar entre disciplinas y dependiendo lo qu e se desee comunicar.

  • En investigación en salud, por ejemplo, a la tabla descriptiva menudo se la conoce como tablas tipo 1.

    • Puede haber más de una, no hay reglas, solo buenos o malos criterios para presentar resultados.

    • A veces separan la tabla 1 en Tabla 1 (toda la población) y tabla 2 (comparación de características)

  • Hay muchos paquetes: {flextable}, {gt},{huxtable}, {kableExtra}, {kable}, etc.

  • Sugerimos {gtsummary} para comenzar: https://www.danieldsjoberg.com/gtsummary/

Tablas descriptivas en R y Stata

  • Varios ado files.

  • El problema con collect es que se requiere mucho código para generar una tabla.

  • Hay varios paquetes que pueden usarse.

  • Podemos dividirlas en dos grandes grupos:

Tablas reproducibles en R

  • Paquetes para construir tablas personalizadas paso a paso:

    • {flextable}
    • {gt}
    • {huxtable}
    • {kable}
    • {kableExtra}
  • Paquetes para construir tablas pre-definidas de manera rápida:

    • {gtsummary}
    • Hay varias más, pero no las tengo mapeadas todas… (en una próxima edición)

Tabla decriptiva reproducible con {gtsummary}

  • Permite crear tablas en formato de revistas biomédicas.

  • Función tbl_summary() para tablas descriptivas univariadas y comparativas (bivariadas)

https://www.danieldsjoberg.com/gtsummary/

Los datos que usaremos

  • Usaremos los datos simulados de un ensayo clínico para evaluar la seguridad de un suplemento en outcomes clinico y fisiologicos de mujeres con menopausia:
id time treat treated age race married2 procedence weight height e2
1 Baseline Placebo 0 33 Mestiza Without couple Callao 59.0 1.4 87.30
1 3 months Placebo 0 32 Mestiza Without couple Callao 59.9 1.3 210.05
2 Baseline Dosis 2 1 27 Mestiza Without couple Santa Anita 62.0 1.5 169.01
2 3 months Dosis 2 1 27 Mestiza Without couple Santa Anita 62.1 1.6 99.91
3 Baseline Dosis 1 1 25 Mestiza Without couple Callao 62.0 1.6 78.76
3 3 months Dosis 1 1 25 Mestiza Without couple Callao 60.0 1.6 155.04
  • Las etiquetas de cada variable son:
Variable Label
id ID participant
time Time's measurement
treat Treatment's group
treated Treated
age Age, years
race Race
married2 Marital status, recat
procedence Distrit of procedence
weight Weight, kg
height Height, m
e2 Estradiol

tbl_summary() paso a paso

tbl_summary() paso a paso

tbl_summary() básico

  • Seleccionar las variables que desea reportar con función select(), luego usar tbl_summary():
library(gtsummary)
datos %>% 
  select(age, race, married2, e2) %>% 
  tbl_summary()

  • Cuarto tipo de resumenes: continuous, continuos2, categorical y dichotomous

  • Por defecto, los estadísticos son reportadas como mediana (percentil 25, percentil 75) para variables numéricas y n (%) para variables categóricas/dicotómicas.

  • Las variables codificadas como 0 / 1, TRUE / FALSE o Yes / No son tratadas como dicotómicas.

  • Los valores NA se listan como “Unknown

  • Los atributos de etiqueta se imprimen por defecto.

  • Uno puede realizar más personalizaciones a la tabla.

Personalización del resultado de tbl_summary()

datos %>% 
  select(age, treated, married2, height, e2) %>% 
  tbl_summary()

Personalización del resultado de tbl_summary()

datos %>% 
  select(age, treated, married2, height, e2) %>% 
  tbl_summary(
    type = list(height ~ "continuous")
  )
  • type: Especifica el tipo de variable para el resumen

Personalización del resultado de tbl_summary()

datos %>% 
  select(age, treated, married2, height, e2) %>% 
  tbl_summary(
    type = list(height ~ "continuous"), 
    statistic = list(
      age ~ "{mean} ({sd})", 
      married2 ~ "{n}  / {N} ({p}%)"
    )
  )
  • type: Especifica el tipo de variable para el resumen.

  • statistic: Personaliza los estadísticos reportados.

Personalización del resultado de tbl_summary()

datos %>% 
  select(age, treated, married2, height, e2) %>% 
  tbl_summary(
    type = list(height ~ "continuous"), 
    statistic = list(
      c(age, height) ~ "{mean} ({sd})", 
      c(married2, treated) ~ "{n}  / {N} ({p}%)"
    )
  )
  • type: Especifica el tipo de variable para el resumen.

  • statistic: Personaliza los estadísticos reportados.

    • Usar c() para varias variables.

Personalización del resultado de tbl_summary()

datos %>% 
  select(age, treated, married2, height, e2) %>% 
  tbl_summary(
    type = list(c(age, height) ~ "continuous2"), 
    statistic = list(
      c(age, height) ~ c("{mean} ({sd})", 
                         "{median} ({p25} - {p75})"), 
      c(married2, treated) ~ "{n}  / {N} ({p}%)"
    )
  )
  • type: Especifica el tipo de variable para el resumen.

  • statistic: Personaliza los estadísticos reportados.

    • Usar c() para varias variables.

    • Si queremos reportar más estadísticos en variables numéricas usamos continuous2

Personalización del resultado de tbl_summary()

datos %>% 
  select(age, treated, married2, height, e2) %>% 
  tbl_summary(
    type = list(c(age, height) ~ "continuous2"), 
    statistic = list(
      c(age, height) ~ c("{mean} ({sd})", 
                         "{median} ({p25} - {p75})", 
                         "{min} - {max}"), 
      c(married2, treated) ~ "{n}  / {N} ({p}%)"
    )
  )
  • type: Especifica el tipo de variable para el resumen.

  • statistic: Personaliza los estadísticos reportados.

    • Usar c() para varias variables.

    • Si queremos reportar más estadísticos en variables numéricas usamos continuous2

      • Podemos ponerle cuantos estadísticos queramos.

Personalización del resultado de tbl_summary()

datos %>% 
  select(age, treated, married2, height, e2) %>% 
  tbl_summary(
    type = list(c(age, height) ~ "continuous2"), 
    statistic = list(
      c(age, height) ~ c("{mean} ({sd})", "{min} - {max}"), 
      c(e2) ~ c("{median} ({p25} - {p75})",
                "{min} - {max}"),       
      c(married2, treated) ~ "{n}  / {N} ({p}%)"
    )
  ) 
  • type: Especifica el tipo de variable para el resumen.

  • statistic: Personaliza los estadísticos reportados.

    • Usar c() para varias variables.

    • Si queremos reportar más estadísticos en variables numéricas usamos continuous2

      • Podemos ponerle cuantos estadísticos queramos.

      • Podemos tener diferentes combinaciones de estadísticos.

Personalización del resultado de tbl_summary()

datos %>% 
  select(age, treated, married2, height, e2) %>% 
  tbl_summary(
    type = list(c(age, height, e2) ~ "continuous2"), 
    statistic = list(
      c(age, height) ~ c("{mean} ({sd})", "{min} - {max}"), 
      c(e2) ~ c("{median} ({p25} - {p75})",
                "{min} - {max}"),       
      c(married2, treated) ~ "{n}  / {N} ({p}%)"
    ), 
    label = list(
      treated ~ "Treated with supplement", e2 ~ "Estradiol, UI",
      married2 ~ "Marital status"
    )
  )
  • type: Especifica el tipo de variable para el resumen.

  • statistic: Personaliza los estadísticos reportados.

  • label: Cambia o personaliza la etiqueta de la variable.

Personalización del resultado de tbl_summary()

datos %>% 
  select(age, treated, married2, height, e2) %>% 
  tbl_summary(
    type = list(c(age, height, e2) ~ "continuous2"), 
    statistic = list(
      c(age, height) ~ c("{mean} ({sd})", "{min} - {max}"), 
      c(e2) ~ c("{median} ({p25} - {p75})",
                "{min} - {max}"),       
      c(married2, treated) ~ "{n}  / {N} ({p}%)"
    ), 
    label = list(
      treated ~ "Treated with supplement", e2 ~ "Estradiol, UI",
      married2 ~ "Marital status"
    ), 
    digits = list(
      c(age) ~ 1, c(height, e2) ~ 2, c(married2, treated) ~ 1
    )
  )
  • type: Especifica el tipo de variable para el resumen.

  • statistic: Personaliza los estadísticos reportados.

  • label: Cambia o personaliza la etiqueta de la variable.

  • digit: Especifica el número de decimales de redondeo.

Reporte de datos perdidos con tbl_summary()

datos %>% 
  select(age, treated, married2, height, e2) %>% 
  tbl_summary(
    type = list(c(age, height, e2) ~ "continuous2"), 
    statistic = list(
      c(age, height) ~ c("{mean} ({sd})", "{min} - {max}"), 
      c(e2) ~ c("{median} ({p25} - {p75})", "{min} - {max}"),       
      c(married2, treated) ~ "{n}  / {N} ({p}%)"
    ), 
    label = list(
      treated ~ "Treated with supplement", e2 ~ "Estradiol, UI",
      married2 ~ "Marital status"
    ), 
    digits = list(
      c(age) ~ 1, c(height, e2) ~ 2, c(married2, treated) ~ 1
    ), 
    missing_text = "Missing data"
  ) 
  • misisng_text: Permite editar la etiqueta de missing (Unknown por defecto).

Reporte de datos perdidos con tbl_summary()

datos %>% 
  select(age, treated, married2, height, e2) %>% 
  tbl_summary(
    type = list(c(age, height, e2) ~ "continuous2"), 
    statistic = list(
      c(age, height) ~ c("{mean} ({sd})", "{min} - {max}"), 
      c(e2) ~ c("{median} ({p25} - {p75})", "{min} - {max}"),       
      c(married2, treated) ~ "{n}  / {N} ({p}%)"
    ), 
    label = list(
      treated ~ "Treated with supplement", e2 ~ "Estradiol, UI",
      married2 ~ "Marital status"
    ), 
    digits = list(
      c(age) ~ 1, c(height, e2) ~ 2, c(married2, treated) ~ 1
    ), 
    missing = "always", missing_text = "Missing data"
  )  
  • misisng_text: Permite editar la etiqueta de missing (Unknown por defecto).

  • missing: Por defecto se presentan los datos perdidos solo si la variable los tiene “ifany”.

    • missing = “always” siempre presenta datos perdidos.

Reporte de datos perdidos con tbl_summary()

datos %>% 
  select(age, treated, married2, height, e2) %>% 
  tbl_summary(
    type = list(c(age, height, e2) ~ "continuous2"), 
    statistic = list(
      c(age, height) ~ c("{mean} ({sd})", "{min} - {max}"), 
      c(e2) ~ c("{median} ({p25} - {p75})", "{min} - {max}"),       
      c(married2, treated) ~ "{n}  / {N} ({p}%)"
    ), 
    label = list(
      treated ~ "Treated with supplement", e2 ~ "Estradiol, UI",
      married2 ~ "Marital status"
    ), 
    digits = list(
      c(age) ~ 1, c(height, e2) ~ 2, c(married2, treated) ~ 1
    ), 
    missing = "no"
  ) 
  • misisng_text: Permite editar la etiqueta de missing (Unknown por defecto).

  • missing: Por defecto se presentan los datos perdidos solo si la variable los tiene “ifany”.

    • missing = “always” siempre presenta datos perdidos, así la variable no los tenga.
    • missing = “no” nunca presenta datos perdidos, así la variable los tenga.

En resumen: {gtsummary} + fórmulas

Personzalización con bold_() / italicize_()

datos %>% 
  select(age, treated, married2, height, e2) %>% 
  tbl_summary(
    type = list(height ~ "continuous"), 
    label = list(
      treated ~ "Treated with supplement", e2 ~ "Estradiol, UI",
      married2 ~ "Marital status"
    ), 
    missing = "ifany"
  ) 

Personzalización con bold_() / italicize_()

datos %>% 
  select(age, treated, married2, height, e2) %>% 
  tbl_summary(
    type = list(height ~ "continuous"), 
    label = list(
      treated ~ "Treated with supplement", e2 ~ "Estradiol, UI",
      married2 ~ "Marital status"
    ), 
    missing = "ifany"
  ) %>% 
  bold_labels()
  • bold_labels(): negrita a las etiquetas de las variables

Personzalización con bold_*() / italicize_*()

datos %>% 
  select(age, treated, married2, height, e2) %>% 
  tbl_summary(
    type = list(height ~ "continuous"), 
    label = list(
      treated ~ "Treated with supplement", e2 ~ "Estradiol, UI",
      married2 ~ "Marital status"
    ), 
    missing = "ifany"
  ) %>% 
  bold_labels() %>% 
  italicize_levels() 
  • bold_labels(): negrita a las etiquetas de las variables

  • italicize_levels(): cursiva a los niveles (valores) de las variables

Guardar tabla como documento MS Word

  • Se puede descargar la tabla en formato MS. Word para reporte reproducible.

  • Primero se guarda como un objeto de R:

datos %>% 
  select(age, treated, married2, height, e2) %>% 
  tbl_summary(
    type = list(height ~ "continuous"), 
    label = list(
      treated ~ "Treated with supplement", e2 ~ "Estradiol, UI",
      married2 ~ "Marital status"
    ), 
    missing = "ifany"
  ) %>% 
  bold_labels() -> tabla1 

tabla1

Guardar tabla como documento MS Word

  • Se puede descargar la tabla en formato MS. Word para reporte reproducible.

  • Primero se guarda como un objeto de R:

datos %>% 
  select(age, treated, married2, height, e2) %>% 
  tbl_summary(
    type = list(height ~ "continuous"), 
    label = list(
      treated ~ "Treated with supplement", e2 ~ "Estradiol, UI",
      married2 ~ "Marital status"
    ), 
    missing = "ifany"
  ) %>% 
  bold_labels() -> tabla1 

tabla1

  • Luego, al objeto se lo guarda como un archivo de MS Word.

Guardar tabla como documento MS Word

  • Se puede descargar la tabla en formato MS. Word para reporte reproducible.

  • Primero se guarda como un objeto de R:

datos %>% 
  select(age, treated, married2, height, e2) %>% 
  tbl_summary(
    type = list(height ~ "continuous"), 
    label = list(
      treated ~ "Treated with supplement", e2 ~ "Estradiol, UI",
      married2 ~ "Marital status"
    ), 
    missing = "ifany"
  ) %>% 
  bold_labels() -> tabla1 

tabla1

  • Luego, al objeto se lo guarda como un archivo de MS Word.
library(flextable)
  • Paso 1: Cargar paquete {flextable}

Guardar tabla como documento MS Word

  • Se puede descargar la tabla en formato MS. Word para reporte reproducible.

  • Primero se guarda como un objeto de R:

datos %>% 
  select(age, treated, married2, height, e2) %>% 
  tbl_summary(
    type = list(height ~ "continuous"), 
    label = list(
      treated ~ "Treated with supplement", e2 ~ "Estradiol, UI",
      married2 ~ "Marital status"
    ), 
    missing = "ifany"
  ) %>% 
  bold_labels() -> tabla1 

tabla1

  • Luego, al objeto se lo guarda como un archivo de MS Word.
library(flextable)

tabla1 %>% 
  as_flex_table() 

  • Paso 1: Cargar paquete {flextable}

  • Paso 2: Se convierte a objeto de tipo flextable con la función as_flex_table().

Guardar tabla como documento MS Word

  • Se puede descargar la tabla en formato MS. Word para reporte reproducible.

  • Primero se guarda como un objeto de R:

datos %>% 
  select(age, treated, married2, height, e2) %>% 
  tbl_summary(
    type = list(height ~ "continuous"), 
    label = list(
      treated ~ "Treated with supplement", e2 ~ "Estradiol, UI",
      married2 ~ "Marital status"
    ), 
    missing = "ifany"
  ) %>% 
  bold_labels() -> tabla1 

tabla1

  • Luego, al objeto se lo guarda como un archivo de MS Word:
library(flextable)

tabla1 %>% 
  as_flex_table() %>% 
  save_as_docx(path = "Tabla1.docx")
  • Paso 1: Cargar paquete {flextable}

  • Paso 2: Se convierte a objeto de tipo flextable con la función as_flex_table().

  • Paso 3: Se guarda como word con la función save_as_docx()

Guardar tabla como documento MS Word (cont.)

  • El MS Word aparecerá en la carpeta del proyecto:

Guardar tabla como documento MS Word (cont.)

  • Y la tabla en Word lucirá así:

Guardar tabla como documento MS Excel

  • Usamos el paquete {huxtable}
library(huxtable)
  • Con la función as_hux_xlsx convertimos el objeto tbl_summary a un excel con un nombre de archivo que uno defina:
tabla1 %>% 
  as_hux_xlsx(file = "Tabla1.xlsx")
  • La tabla en excel se muestra a continuación:

Nuestro turno


  • Genere algunas tabla reproducibles con tbl_summary().

  • Exporte las tablas a MS Word.

  • Exporte las tablas a MS Excel.


30:00

Visualización de datos con R

Visualización de datos con R

Visualización de datos


“The simple graph has brought more information to the data analyst’s mind than any other device.” — John Tukey

  • La visualización de datos es la creación y el estudio de la representación visual de los datos.

  • Muchas herramientas para visualizar datos, R es una de ellas.

  • Muchos enfoques/sistemas dentro de R para hacer visualizaciones de datos

    • {ggplot2} es uno de ellos, y eso es lo que vamos a usar

Gramática de gráficos


 

  • Una gramática de gráficos es una herramienta que nos permite describir de manera concisa los componentes de un gráfico.

  • Es un lenguaje que permite dibujar un gráfico con palabras sencillas.

  • Uno puede describir el proceso de dibujar el gráfico con sus propias palabras y estas convertirse en gráfico.

{ggplot2} es un paquete de {tidyverse}



  • {ggplot2} es el paquete de visualización de datos de tidyverse.

  • gg en {ggplot2} significa Gramática de gráficos.

  • Inspirado en el libro Grammar of Graphics de Leland Wilkinson

Evolución de los gráficos estadisticos


Primeros pasos con {ggplot2}


  • Data disponible en paquete {dslabs}.
library(dslabs)
data(gapminder, package = "dslabs") 

  • Veamos los datos:
  • Veamos el detalle
?gapminder

  • En algunos casos, trabajaremos con los datos del año 2000:
gapminder2000 <- gapminder %>% 
  filter(year == 2000)
  • En algunos casos, trabajaremos con los datos del año 1980 y 2000:
gapminder1980_2000 <- gapminder %>% 
  filter(year %in% c(1980, 2000))

Aspectos básicos de {ggplot2}


  • Estructura de código para generar gráficos en {ggplot2}
ggplot(data = [dataset], 
       mapping = aes(x = [x_variable], 
                     y = [y_variable])) +
   geom_xxx() +
   other options

Componentes de {ggplot2}


Pasos para un gráfico {ggplot2}


Inicia con el data.frame gapminder

ggplot(data = gapminder)

Inicia con el data.frame gapminder, mapea year a x

ggplot(data = gapminder, 
       mapping = aes(x = year))

Inicia con el data.frame gapminder, mapea year a x y mapea life_expectancy a y

ggplot(data = gapminder, 
       mapping = aes(x = year, 
                     y = life_expectancy))

Inicia con el data.frame gapminder, mapea year a x y mapea life_expectancy a y. Representa cada información con un punto

ggplot(data = gapminder, 
       mapping = aes(x = year, 
                     y = life_expectancy)) + 
  geom_point()

Inicia con el data.frame gapminder, mapea year a x y mapea life_expectancy a y. Representa cada información con un punto. Mapea continent al color de los puntos

ggplot(data = gapminder, 
       mapping = aes(x = year, 
                     y = life_expectancy, 
                     colour = continent)) + 
  geom_point()

Inicia con el data.frame gapminder, mapea year a x y mapea life_expectancy a y. Representa cada información con un punto. Mapea continent al color de los puntos. Titula el gráfico como “Esperanza de vida a lo largo del tiempo”

ggplot(data = gapminder, 
       mapping = aes(x = year, 
                     y = life_expectancy, 
                     colour = continent)) + 
  geom_point() + 
  labs(title = "Esperanza de vida a lo largo del tiempo")

Inicia con el data.frame gapminder, mapea year a x y mapea life_expectancy a y. Representa cada información con un punto. Mapea continent al color de los puntos. Titula el gráfico como “Esperanza de vida a lo largo del tiempo” y agrega el subtitulo “Datos para Africa, Americas, Asia, Europa y Oceania”

ggplot(data = gapminder, 
       mapping = aes(x = year, 
                     y = life_expectancy, 
                     colour = continent)) + 
  geom_point() + 
  labs(title = "Esperanza de vida a lo largo del tiempo", 
       subtitle = "Datos para Africa, Americas, Asia, Europa y Oceania")

Inicia con el data.frame gapminder, mapea year a x y mapea life_expectancy a y. Representa cada información con un punto. Mapea continent al color de los puntos. Titula el gráfico como “Esperanza de vida a lo largo del tiempo” y agrega el subtitulo “Datos para Africa, Americas, Asia, Europa y Oceania”. Etiqueta los ejes x e y como “Año” y “Esperanza de Vida”, respectivamente

ggplot(data = gapminder, 
       mapping = aes(x = year, 
                     y = life_expectancy, 
                     colour = continent)) + 
  geom_point() + 
  labs(title = "Esperanza de vida a lo largo del tiempo", 
       subtitle = "Datos para Africa, Americas, Asia, Europa y Oceania", 
       x = "Año", y = "Esperanza de Vida")

Inicia con el data.frame gapminder, mapea year a x y mapea life_expectancy a y. Representa cada información con un punto. Mapea continent al color de los puntos. Titula el gráfico como “Esperanza de vida a lo largo del tiempo” y agrega el subtitulo “Datos para Africa, Americas, Asia, Europa y Oceania”. Etiqueta los ejes x e y como “Año” y “Esperanza de Vida”, respectivamente. Etiqueta la leyenda como “Continentes”

ggplot(data = gapminder, 
       mapping = aes(x = year, 
                     y = life_expectancy, 
                     colour = continent)) + 
  geom_point() + 
  labs(title = "Esperanza de vida a lo largo del tiempo", 
       subtitle = "Datos para Africa, Americas, Asia, Europa y Oceania", 
       x = "Año", y = "Esperanza de Vida", 
       colour = "Continentes")

Inicia con el data.frame gapminder, mapea year a x y mapea life_expectancy a y. Representa cada información con un punto. Mapea continent al color de los puntos. Titula el gráfico como “Esperanza de vida a lo largo del tiempo” y agrega el subtitulo “Datos para Africa, Americas, Asia, Europa y Oceania”. Etiqueta los ejes x e y como “Año” y “Esperanza de Vida”, respectivamente. Etiqueta la leyenda como “Continentes” y agrega un titulo para la fuente de datos

ggplot(data = gapminder, 
       mapping = aes(x = year, 
                     y = life_expectancy, 
                     colour = continent)) + 
  geom_point() + 
  labs(title = "Esperanza de vida a lo largo del tiempo", 
       subtitle = "Datos para Africa, Americas, Asia, Europa y Oceania", 
       x = "Año", y = "Esperanza de Vida", 
       colour = "Continentes", 
       caption = "Fuente: Gapminder data")

Inicia con el data.frame gapminder, mapea year a x y mapea life_expectancy a y. Representa cada información con un punto. Mapea continent al color de los puntos. Titula el gráfico como “Esperanza de vida a lo largo del tiempo” y agrega el subtitulo “Datos para Africa, Americas, Asia, Europa y Oceania”. Etiqueta los ejes x e y como “Año” y “Esperanza de Vida”, respectivamente. Etiqueta la leyenda como “Continentes” y agrega un titulo para la fuente de datos. Finalmente, usa una escala de colores discreta que esté diseñada para preservar la visualización de personas con formas comunes discapacidad visual para los colores

ggplot(data = gapminder, 
       mapping = aes(x = year, 
                     y = life_expectancy, 
                     colour = continent)) + 
  geom_point() + 
  labs(title = "Esperanza de vida a lo largo del tiempo", 
       subtitle = "Datos para Africa, Americas, Asia, Europa y Oceania", 
       x = "Año", y = "Esperanza de Vida", 
       colour = "Continentes", 
       caption = "Fuente: Gapminder data") + 
  scale_colour_viridis_d()

En resumen


ggplot(data = gapminder, 
       mapping = aes(x = year, 
                     y = life_expectancy, 
                     colour = continent)) + 
  geom_point() + 
  labs(title = "Esperanza de vida a lo largo del tiempo", 
       subtitle = "Datos para Africa, Americas, Asia, Europa y Oceania", 
       x = "Año", y = "Esperanza de Vida", 
       colour = "Continentes", 
       caption = "Fuente: Gapminder data") + 
  scale_colour_viridis_d()

Inicia con el data.frame gapminder, mapea year a x y mapea life_expectancy a y.

Representa cada información con un punto.

Mapea continent al color de los puntos.

Titula el gráfico como “Esperanza de vida a lo largo del tiempo” y agrega el subtitulo “Datos para Africa, Americas, Asia, Europa y Oceania”.

Etiqueta los ejes x e y como “Año” y “Esperanza de Vida”, respectivamente.

Etiqueta la leyenda como “Continentes” y agrega un titulo para la fuente de datos.

Finalmente, usa una escala de colores discreta que esté diseñada para preservar la visualización de personas con formas comunes discapacidad visual para los colores.

Nombre de argumentos


Se puede omitir los nombres de los dos primeros argumentos cuando construimos gráficos con {ggplot2}.

ggplot(data = gapminder, 
       mapping = aes(x = gdp, 
                     y = life_expectancy, 
                     colour = continent)) + 
  geom_point() + 
  scale_colour_viridis_d()

ggplot(gapminder, 
       aes(x = gdp, 
           y = life_expectancy, 
           colour = continent)) + 
  geom_point() + 
  scale_colour_viridis_d()

Transformar variables para mejorar visualización


Se puede realizar transformaciones sobre la marcha de las variables en los gráficos de {ggplot2}.

ggplot(data = gapminder2000, 
       mapping = aes(x = gdp, 
                     y = life_expectancy, 
                     colour = continent)) + 
  geom_point() + 
  labs(title = "PBI y esperanza de vida", 
       subtitle = "Datos para Africa, Americas, Asia, Europa y Oceania", 
       x = "Producto Bruto Interno", 
       y = "Esperanza de Vida", 
       colour = "Continentes", 
       caption = "Fuente: Gapminder data") + 
  scale_colour_viridis_d()

ggplot(data = gapminder2000, 
       mapping = aes(x = log(gdp), #< Ponemos log()
                     y = life_expectancy, 
                     colour = continent)) + 
  geom_point() + 
  labs(title = "PBI y esperanza de vida", 
       subtitle = "Datos para Africa, Americas, Asia, Europa y Oceania", 
       x = "Logaritmo de Producto Bruto Interno", #< Editamos nombre
       y = "Esperanza de Vida", 
       colour = "Continentes", 
       caption = "Fuente: Gapminder data") + 
  scale_colour_viridis_d()

Nuestro turno


 

  • Con la data de gapminder, hagamos algunos gráficos.
10:00

Estéticas

Opciones de estéticas


 

Las características comunmente usadas en los gráficos que pueden ser mapeadas a variables específicas en los datos:

  • color

  • forma

  • tamaño

  • alfa (transparencia)

Color


ggplot(data = gapminder2000, 
       mapping = aes(x = log(gdp), 
                     y = life_expectancy, 
                     colour = continent)) + 
  geom_point() + 
  scale_colour_viridis_d()

Forma


  • Forma mapeada a variable adicional
ggplot(data = gapminder2000, 
       mapping = aes(x = log(gdp), 
                     y = life_expectancy, 
                     colour = continent, 
                     shape = region)) + 
  geom_point() + 
  scale_colour_viridis_d()

Forma


  • Forma mapeada a la misma variable
ggplot(data = gapminder2000, 
       mapping = aes(x = log(gdp),  
                     y = life_expectancy, 
                     colour = continent, 
                     shape = continent)) + 
  geom_point() + 
  scale_colour_viridis_d()

Tamaño


ggplot(data = gapminder2000, 
       mapping = aes(x = log(gdp),  
                     y = life_expectancy, 
                     colour = continent, 
                     shape = continent, 
                     size = population)) + 
  geom_point() + 
  scale_colour_viridis_d()

Alfa


ggplot(data = gapminder2000, 
       mapping = aes(x = log(gdp), 
                     y = life_expectancy, 
                     colour = continent, 
                     shape = continent, 
                     size = population, 
                     alpha = population)) + 
  geom_point() + 
  scale_colour_viridis_d()

Mapeo versus Configuración


Mapeo

ggplot(data = gapminder2000, 
       mapping = aes(x = log(gdp), 
                     y = life_expectancy, 
                     colour = continent, 
                     shape = continent, 
                     size = population, 
                     alpha = population)) + 
  geom_point() + 
  scale_colour_viridis_d()

Configuración

ggplot(data = gapminder2000, 
       mapping = aes(x = log(gdp),  
                     y = life_expectancy, 
                     colour = continent, 
                     shape = continent)) + 
  geom_point(size = 2, alpha = 0.5) + 
  scale_colour_viridis_d()

Mapeo vs. Configuración


  • Mapeo: Determina el tamaño, alfa, etc. de los puntos basados en el valor de un variable en los datos:

    • Conocido en inglés como mapping.

    • Se configura como: aes()

  • Configuración: Determina el tamaño, alfa, etc. de los puntos SIN basarse en el valor de un variable en los datos:

    • Conocido en inglés como setting.

    • Se configura como: geom_* (en este caso fue geom_point, pero hay otras geometrías más)

Temas pre-definidos de {ggplot2}


 

  • {ggplot2} ofrece una serie de temas predinidos.

  • Un tema predefinido es una configuración pre-definida de componentes no dependientes de los datos (títulos, etiquetas, fuentes, fondo, grilas, leyendas, etc.) que pueden ser usados para darle un aspecto consistente a los gráficos.

  • Más info sobre los temas completas pre-definidos se pueden encontra en el siguiente enlace: Ver aquí.

  • Uno también puede personalizar sus propios temas: Ver aquí.

Temas completos


  • theme_gray (por defecto)

  • theme_bw()

  • theme_linedraw()

  • theme_light()

ggplot(data = gapminder2000, 
       mapping = aes(x = log(gdp), 
                     y = life_expectancy, 
                     colour = continent, 
                     shape = continent)) + 
  geom_point(size = 2, alpha = 0.5) + 
  scale_colour_viridis_d() + 
  theme_gray()

ggplot(data = gapminder2000, 
       mapping = aes(x = log(gdp), 
                     y = life_expectancy, 
                     colour = continent, 
                     shape = continent)) + 
  geom_point(size = 2, alpha = 0.5) + 
  scale_colour_viridis_d() + 
  theme_bw()

ggplot(data = gapminder2000, 
       mapping = aes(x = log(gdp), 
                     y = life_expectancy, 
                     colour = continent, 
                     shape = continent)) + 
  geom_point(size = 2, alpha = 0.5) + 
  scale_colour_viridis_d() + 
  theme_linedraw()

ggplot(data = gapminder2000, 
       mapping = aes(x = log(gdp), 
                     y = life_expectancy, 
                     colour = continent, 
                     shape = continent)) + 
  geom_point(size = 2, alpha = 0.5) + 
  scale_colour_viridis_d() + 
  theme_light()

Temas completos (parte 2)


  • theme_dark()

  • theme_minimal()

  • theme_classic()

  • theme_void()

  • theme_test()

ggplot(data = gapminder2000, 
       mapping = aes(x = log(gdp), 
                     y = life_expectancy, 
                     colour = continent, 
                     shape = continent)) + 
  geom_point(size = 2, alpha = 0.5) + 
  scale_colour_viridis_d() + 
  theme_dark()

ggplot(data = gapminder2000, 
       mapping = aes(x = log(gdp), 
                     y = life_expectancy, 
                     colour = continent, 
                     shape = continent)) + 
  geom_point(size = 2, alpha = 0.5) + 
  scale_colour_viridis_d() + 
  theme_minimal()

ggplot(data = gapminder2000, 
       mapping = aes(x = log(gdp), 
                     y = life_expectancy, 
                     colour = continent, 
                     shape = continent)) + 
  geom_point(size = 2, alpha = 0.5) + 
  scale_colour_viridis_d() + 
  theme_classic()

ggplot(data = gapminder2000, 
       mapping = aes(x = log(gdp), 
                     y = life_expectancy, 
                     colour = continent, 
                     shape = continent)) + 
  geom_point(size = 2, alpha = 0.5) + 
  scale_colour_viridis_d() + 
  theme_void()

ggplot(data = gapminder2000, 
       mapping = aes(x = log(gdp), 
                     y = life_expectancy, 
                     colour = continent, 
                     shape = continent)) + 
  geom_point(size = 2, alpha = 0.5) + 
  scale_colour_viridis_d() + 
  theme_test()

Facetado


  • Se puede dividir la imagen en varias subimágenes de acuerdo a alguna otra condición.

  • Muy útil cuando se tienen grandes de datos y es de interés mostrar sus relaciones con varias variables.

  • Hay dos tipos de facetado:

    • facet_grid

    • facet_wrap

Facetado


ggplot(data = gapminder, 
       mapping = aes(x = year, 
                     y = life_expectancy)) + 
  geom_point() + 
  facet_grid(continent ~ .) + 
  scale_colour_viridis_d() + 
  theme_bw()

ggplot(data = gapminder2000, 
       mapping = aes(x = log(gdp), 
                     y = life_expectancy)) + 
  geom_point() + 
  facet_grid(. ~ continent) + 
  scale_colour_viridis_d() + 
  theme_bw()

ggplot(data = gapminder2000, 
       mapping = aes(x = log(gdp), 
                     y = life_expectancy)) + 
  geom_point() + 
  facet_wrap(continent ~ . ) + 
  scale_colour_viridis_d() + 
  theme_bw()
ggplot(data = gapminder2000, 
       mapping = aes(x = log(gdp), 
                     y = life_expectancy)) + 
  geom_point() + 
  facet_wrap(. ~ continent) + 
  scale_colour_viridis_d() + 
  theme_bw()

ggplot(data = gapminder1980_2000, 
       mapping = aes(x = log(gdp), 
                     y = life_expectancy)) + 
  geom_point() + 
  facet_grid(year ~ continent) + 
  scale_colour_viridis_d() + 
  theme_bw()

Nuestro turno


  • Mejoremos los gráficos realizados con ggplot2.

 

10:00

¡Gracias!
¿Preguntas?




https://github.com/psotob91

percys1991@gmail.com